package own.stu.jobgib.playown.redis.redisson;

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * all success then do sth
 */
@Slf4j
public class AllS {

    public static void main(String[] args) throws InterruptedException {
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        List<String> businesses = Arrays.asList("aa", "ef", "ffff");

        final Stopwatch watch = Stopwatch.createStarted();
        log.info("start : {}", watch.toString());
        for (String business : businesses) {
            CompletableFuture<Void> promise = new CompletableFuture<>();

            futures.add(promise);

            CompletableFuture<Integer> businessFuture = dealBusiness(business);
            businessFuture.thenCompose(res -> {
                promise.complete(null);
                return null;
            });
        }

        CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        allOf.whenComplete((v, s) -> {
            watch.stop();
            log.info("all done, {}", watch.toString());
        });
        TimeUnit.SECONDS.sleep(3);
    }

    private final static ExecutorService service = Executors.newFixedThreadPool(5);
    private static final ThreadLocalRandom random = ThreadLocalRandom.current();

    public static CompletableFuture<Integer> dealBusiness(String data) {
        return CompletableFuture.supplyAsync(() -> {
            int num = 0;
            try {
                num = random.nextInt(120, 200);
                TimeUnit.MILLISECONDS.sleep(num);
            } catch (InterruptedException e) {
                log.error(" ------- ");
            }
            log.info("{} - [{}] deal: {}, cost: {}", new Date(), Thread.currentThread().getName(), data, num);
            return num;
        });
    }

    private static Future<Integer> dealBusiness_bad(String data) {
        return service.submit(() -> {
            int num = 0;
            try {
                num = random.nextInt(100, 200);
                TimeUnit.MILLISECONDS.sleep(num);
            } catch (InterruptedException e) {
                log.error(" ------- ");
            }
            log.info("{} deal: {}", Thread.currentThread().getName(), data);
            return num;
        });
    }
}
